/*
 * Author: Alberto De Pena
 * Applied Algorithms
 * semigrp.cpp
*/

#include <iostream>
#include <fstream>
using namespace std;

void main()
{
    ifstream fin;
    ofstream fout;

	fin.open( "semigrp.in" );
    fout.open( "semigrp.out" );

    int i, j, k, n, row, col;
	int maximunSet, ROW, COL, element;
	int associative1, associative2, associative3, commutative1, commutative2;
	int firstCommutativeRow, secondCommutativeRow, firstCommutativeCol, secondCommutativeCol;
	int firstAssociativeRow, secondAssociativeRow, firstAssociativeCol, secondAssociativeCol;
	int newRow, newCol, nextCol, nextRow;

    char Letters[26], tableOutPut[26][26];
	char commFinal1, commFinal2;
	char final1, final2;

    bool semigroup, bad, associative, commutative, first_set;
	
    fin >> n;
    while( n != 0 && !fin.eof() )
    {
        semigroup = true;
        bad = false;
        associative = true;
        commutative = true;
        maximunSet = 0;
        for( i = 0; i < n; i++ )
        {
            fin >> Letters[i];
            if( (int)Letters[i] - 97 > maximunSet )
                maximunSet = (int)Letters[i] - 97;
        }

        fout << "S = {";
        first_set = true;
        for( i = 0; i < n; i++ )
        {
            if( first_set )
                first_set = false;
            else
                fout << ",";
            fout << Letters[i];
                
        }
        fout << "}" << endl;

        fout << " #|";
        for( i = 0; i < n; i++ )
            fout << Letters[i];

        fout << endl;

        fout << " -+";
        for( i = 0; i < n; i++ )
            fout << "-";

        fout << endl;
        for( i = 0; i < n; i++ )
        {
            for( j = 0; j < n; j++ )
            {
                row = (int)Letters[i] - 97;
                col = (int)Letters[j] - 97;
                fin >> tableOutPut[row][col];
                if( (int)tableOutPut[row][col] - 97 > maximunSet )
                {
                    semigroup = false;
                    bad = true;
                    ROW = row + 97;
                    COL = col + 97;

                    element = tableOutPut[row][col];
                }
            }
        }

        for( i = 0; i < n && associative; i++ )
        {
            for( j = 0; j < n && associative; j++ )
            {
                for( k = 0; k < n && associative; k++ )
                {
                    firstAssociativeRow = (int)Letters[i] - 97;
                    firstAssociativeCol = (int)Letters[j] - 97;
                    nextCol = (int)Letters[k] - 97;
                    newRow = (int)tableOutPut[firstAssociativeRow][firstAssociativeCol] - 97;
                    final1 = tableOutPut[newRow][nextCol];

                    secondAssociativeRow = (int)Letters[j] - 97;
                    secondAssociativeCol = (int)Letters[k] - 97;
                    nextRow = (int)Letters[i] - 97;
                    newCol = (int)tableOutPut[secondAssociativeRow][secondAssociativeCol] - 97;
                    final2 = tableOutPut[nextRow][newCol];
                    
                    if( final1 != final2 )
                    {
                        associative = false;
                        semigroup = false;

                        associative1 = firstAssociativeRow + 97;
                        associative2 = firstAssociativeCol + 97;
                        associative3 = nextCol + 97;
                    }
                }
            }
        }

        if( semigroup )
        {
            for( i = 0; i < n && commutative; i++ )
            {
                for( j = 0; j < n && commutative; j++ )
                {
                    firstCommutativeRow = (int)Letters[i] - 97;
                    firstCommutativeCol = (int)Letters[j] - 97;

                    commFinal1 = tableOutPut[firstCommutativeRow][firstCommutativeCol];

                    secondCommutativeRow = (int)Letters[j] - 97;
                    secondCommutativeCol = (int)Letters[i] - 97;

                    commFinal2 = tableOutPut[secondCommutativeRow][secondCommutativeCol];

                    if( commFinal1 != commFinal2 )
                    {
                        commutative = false;

                        commutative1 = firstCommutativeRow + 97;
                        commutative2 = firstCommutativeCol + 97;
                    }
                }
            }
        }

        for( i = 0; i < n; i++ )
        {
            fout << " " << Letters[i] << "|";
            for( j = 0; j < n; j++ )
            {
                row = (int)Letters[i] - 97;
                col = (int)Letters[j] - 97;

                fout << tableOutPut[row][col];
            }
            fout << endl;
        }
        fout << endl;

        if( semigroup )
        {
            if( commutative )
            {
                fout << "COMMUTATIVE SEMIGROUP" << endl;
            }   
            else
            {
                fout << "SEMIGROUP BUT NOT COMMUTATIVE (" << (char)commutative1 << "#" << (char)commutative2 
				<< " IS NOT EQUAL TO " << (char)commutative2 << "#" << (char)commutative1 << ")" << endl;
            }
        }
        else
        {
            if( bad )
            {
                fout << "NOT A SEMIGROUP: " << (char)ROW << "#" << (char)COL << " = " <<
                (char)element << " WHICH IS NOT AN ELEMENT OF THE SET" << endl;
            }
            else
            {
                fout << "NOT A SEMIGROUP: (" << (char)associative1 << "#" << (char)associative2 << ")#" << (char)associative3 
				<< " IS NOT EQUAL TO " << (char)associative1 << "#(" << (char)associative2 << "#" << (char)associative3 << ")" << endl;
            }
        }
        fout << "------------------------------" << endl << endl;
        fin >> n;
    }

    fin.close();
    fout.close();
}

